package com.xuecheng.producer;

import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.ConnectionFactory;
import java.io.IOException;
import java.util.concurrent.TimeoutException;
/**
 * @author: gongfy
 * @create: 2020/7/14 15:46
 * @Description: rabbitMQ入门程序  生产者
 */
public class Producer01 {
    //队列名称
    private static final String QUEUE = "Hello RabbitMQ";

    public static void main(String[] args) throws IOException, TimeoutException {
        Connection connection = null;
        Channel channel = null;
        try {
            // 通过连接工厂创建新的连接和MQ建立连接
            ConnectionFactory factory = new ConnectionFactory();
            factory.setHost("localhost");
            factory.setPort(5672);  //  注意不是：http://localhost:15672 web管理端端口  通信端口是：5672
            factory.setUsername("guest");
            factory.setPassword("guest");
            factory.setVirtualHost("/");//rabbitmq默认虚拟机名称为“/”，一个mq服务可以设置多个虚拟机，每一个相当于一个独立的mq服务器
            //1.创建与RabbitMQ服务的TCP连接
            connection = factory.newConnection();
            //2.创建与Exchange的会话通道，每个连接可以创建多个通道，每个通道代表一个会话任务
            channel = connection.createChannel();
            /**  目的：需要给队列发送消息
             * 3.声明队列：如果Rabbit中没有此队列将自动创建  queueDeclare(String queue, boolean durable, boolean exclusive, boolean autoDelete, Map<String, Object> arguments)
             * queue:队列名称
             * durable:是否持久化，如果持久化重启后队列还在
             * exclusive:队列是否独占此连接  队列只允许在该连接中访问，如果连接关闭则自动删除。设置true可用于临时队列的创建
             * autoDelete:队列不再使用时是否自动删除此队列， 如果将此参数和exclusive设置为true就可以实现临时队列（不用了就自动删除）
             * arguments:队列参数  可以设置一些扩展参数，比如，可设置存活时间
             */
            channel.queueDeclare(QUEUE, true, false, false, null);
            String message = "Hello RabbitMQ JamesFeiyue！！！" + System.currentTimeMillis();
            /**
             * 4.消息发布方法   basicPublish(String exchange, String routingKey, BasicProperties props, byte[] body)
             * exchange：Exchange的名称，如果没有指定，则使用Default Exchange
             * routingKey: 消息的路由Key，交换机根据路由key将消息转发到指定的队列，如果使用默认交换机，routingKey设置为队列的名称
             * props:消息包含的属性 ，属性一般不用可以放在消息体中
             * body：消息体
             */
            channel.basicPublish("", QUEUE, null, message.getBytes());
            System.out.println("Send Message To MQ:'" + message + "'");
        } catch (Exception ex) {
            ex.printStackTrace();
        } finally {
            if (channel != null) {
                channel.close();
            }
            if (connection != null) {
                connection.close();
            }
        }
    }
}
